/*
根据程序输入的命令行参数，删除、复制、移动、重命名文件
判断用户输入是否有效

DeleteFile、CopyFile、MoveFile、SetFileAttributes函数
_tprintf、_tscanf_s函数
_countof、TEXT宏
GetLastError函数
fflush、getchar函数
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define DEL "-d"
#define MOVE "-m"
#define COPY "-c"

void DelFileFunc(PCTSTR FileName);
void CopyFileFunc(PCTSTR SrcFileName, PCTSTR NewFileName);
void MoveRenFileFunc(PCTSTR SrcFileName, PCTSTR NewFileName);

int main(int argc, PCTSTR argv[])
{
    // 删除文件
    if ((lstrcmp(*(argv+1), DEL)==0) && argc==3) {
        DelFileFunc(*(argv+2));
    // 复制文件
    } else if ((lstrcmp(*(argv+1), COPY)==0) && argc==4) {
        CopyFileFunc(*(argv+2), *(argv+3));
    // 移动、重命名
    } else if ((lstrcmp(*(argv+1), MOVE)==0) && argc==4) {
        MoveRenFileFunc(*(argv+2), *(argv+3));
    } else {
        _tprintf(TEXT("输入的命令行参数有误。输入的参数形式如下：\n-d 文件路径\n-c 文件路径1 文件路径2\n-m 文件路径1 文件路径2\n"));
    }

    return 0;
}

/* 删除文件（不能删除目录） */
void DelFileFunc(PCTSTR FileName)
{
    if (SetFileAttributes(FileName, FILE_ATTRIBUTE_NORMAL)==TRUE) {
        _tprintf(TEXT("成功将 %s 的属性设置为正常属性。\n"), FileName);
    } else {
        _tprintf(TEXT("设置 %s 属性出错。错误代码是： %lu\n"), FileName, GetLastError());        
    }

    if (DeleteFile(FileName)!=0) {
        _tprintf(TEXT("成功删除 %s 。\n"), FileName);
    } else {
        _tprintf(TEXT("删除 %s 。错误代码是： %lu\n"), FileName, GetLastError());
    }
}

/* 复制文件 */
void CopyFileFunc(PCTSTR SrcFileName, PCTSTR NewFileName)
{
    TCHAR szChoices[2];
    TCHAR ch;
    BOOL bFailIfExists = TRUE;

    // bFailIfExists值为TRUE，不覆盖已经存在的文件
    // 如果文件存在，返回失败
    // GetLastError函数获取错误代码（返回80/0x50）
    if ((CopyFile(SrcFileName, NewFileName, TRUE)==0) && GetLastError()==0x50) {
        _tprintf(TEXT(" %s 文件已存在。\n是否要覆盖复制（覆盖，输入Y；输入其余字符，不覆盖。）。\n请输入你的选择： "), NewFileName);
        
        // 获取用户的选择：是否覆盖
        // y或Y，覆盖
        // y或Y前后可以有空格或制表符，但如果包含其他字符，视为无效输入
        if ((_tscanf_s("%1s", szChoices, (unsigned)_countof(szChoices))==1) && ((lstrcmp(szChoices, "y")==0) || (lstrcmp(szChoices, "Y"))==0)) {
            bFailIfExists = FALSE;
        }

        //  y或Y前后可以有空格或制表符，但如果包含其他字符，视为无效输入
        // 判断y或Y的后面有无非空格和非制表符的其他字符
        while ((ch=getchar())!='\n') {
            if (ch!=' ' && ch!='\t') {
                bFailIfExists = TRUE;
                break;
            }
        }

        // 清空输入缓冲区
        fflush(stdin);

        if (bFailIfExists==TRUE) {
            _tprintf(TEXT("你选择了不覆盖文件。复制操作取消。\n"));
        } else if (CopyFile(SrcFileName, NewFileName, FALSE)==0) {
            _tprintf(TEXT("复制文件 %s 至 %s 失败。错误代码是： %lu \n"), SrcFileName, NewFileName, GetLastError());
        } else {
            _tprintf(TEXT("你选择了覆盖文件。成功将文件 %s 复制至 %s 。\n"), SrcFileName, NewFileName);
        }
    } else {
        _tprintf(TEXT("成功将文件 %s 复制至 %s 。\n"), SrcFileName, NewFileName);
    }
}

/* 移动、重命名 */
void MoveRenFileFunc(PCTSTR SrcFileName, PCTSTR NewFileName)
{
    if (MoveFile(SrcFileName, NewFileName)) {
        _tprintf(TEXT("成功将文件 %s 移动至 %s 。\n"), SrcFileName, NewFileName);
    } else {
        _tprintf(TEXT("移动文件 %s 至 %s 失败。错误代码是： %lu \n"), SrcFileName, NewFileName, GetLastError());
    }
}